package cn.nawang.ebeim.api.controller;


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import cn.nawang.ebeim.api.domain.UserBeHaviorsLog;
import cn.nawang.ebeim.api.service.UserBehaviorsLogService;

/**
 * @ClassName: MyTaskAnnotation
 * @Description: TODO(启动一个定时task扫描上传目录，并且插入到数据库)
 * @author 阮志忠
 * @date 2015年11月19日 上午9:19:16
 * 
 */
@Component
public class MyTaskAnnotation {
    private static final Logger LOG = LoggerFactory.getLogger(MyTaskAnnotation.class);
    private boolean isRunning = false;
    /** 
    * @Fields expireTime : TODO(日志过期删除时间 按天算) 
    */ 
    private int expireTime = 7;
    
    @Autowired
    private UserBehaviorsLogService userBehaviorsLogService;

    
    /**
     * @Fields uploadPath : TODO(文件上传的路径)
     */
    public static String uploadPath;

    /**
     * @Fields isRunning : 保证每次只有一个task在跑，如果有多个task会导致插入的log重复和文件锁等bug
     */
    public static String getUploadPath() {
        return uploadPath;
    }

    
    
    public int getExpireTime() {
        return expireTime;
    }

    public void setExpireTime(int expireTime) {
        this.expireTime = expireTime;
    }


    /**
     * @Title: setUploadPath @Description: TODO(根据配置注入文件上传的路径) @param @return void @throws
     */
    public void setUploadPath(String uploadPath) {
        if (MyTaskAnnotation.uploadPath == null && uploadPath != null) {
            File file = new File(uploadPath);
            if (!file.exists()) {
                file.mkdirs();
            }
            MyTaskAnnotation.uploadPath = uploadPath;
        }
    }



    /**
     * @Title: findLog @Description: TODO(定时任务每隔60s扫描一次上传的目录) @param @return void @throws
     */
    @Scheduled(fixedRate = 1000 * 60)
    public synchronized void findLog() {
        if (isRunning) {
            return;
        }

        isRunning = true;
        
        File dir = new File(uploadPath);
        File[] files = dir.listFiles(new FilenameFilter() {
            
            @Override
            public boolean accept(File dir, String name) {
                if(name.endsWith(".bhs")){
                    return true;
                }
                return false;
            }
        });
        if(files.length>0){
            userBehaviorsLogService.deleteExpireBackupLog(new Date(new Date().getTime()-expireTime*86400000));
            saveAllLogs(files, 0);
        }
        isRunning = false;
    }

    /**
     * @Title: saveAllLogs @Description: TODO(递归调用批量插入本次所扫描到的所有日志，写入完毕后删除log文件) @param @return
     * void @throws
     */
    private void saveAllLogs(File[] files, int index) {
        if (index < files.length) {
            try {
                File file = files[index];
                List<UserBeHaviorsLog> userBeHaviorsLogs = getUserBeHaviorsLogList(file);
                userBehaviorsLogService.bulkInsert(userBeHaviorsLogs);
                file.delete();
            } catch (Exception e) {
                e.printStackTrace();
            }
            saveAllLogs(files, ++index);
        }
    }

    /**
     * @Title: getUserBeHaviorsLogList @Description: TODO(按行读取文件) @param @return
     * List<UserBeHaviorsLog> @throws
     */
    private List<UserBeHaviorsLog> getUserBeHaviorsLogList(File file) throws Exception {
        String fileName = file.getName();
        String userID = fileName.substring(fileName.indexOf("-")+1, fileName.indexOf("."));
        FileInputStream fis = new FileInputStream(file);
        InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
        BufferedReader br = new BufferedReader(isr);
        String line = "";
        List<UserBeHaviorsLog> list = new ArrayList<UserBeHaviorsLog>();
        
        try {
            while ((line = br.readLine()) != null) {
                UserBeHaviorsLog beHaviorsLog = getUserBeHaviorsLog(line);
                if (beHaviorsLog != null){ 
                    beHaviorsLog.setUserID(userID);
                    list.add(beHaviorsLog);
                };
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
                isr.close();
                fis.close();
            } catch (IOException e) {}
        }
        return list;
    }

    /**
     * @Title: getUserBeHaviorsLog @Description: TODO(将每行字符串转为 UserBeHaviorsLog 对象) @param @return
     * UserBeHaviorsLog @throws
     */
    private UserBeHaviorsLog getUserBeHaviorsLog(String line) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            UserBeHaviorsLog beHaviorsLog = mapper.readValue(line, UserBeHaviorsLog.class);
            beHaviorsLog.setId(UUID.randomUUID().toString());
            return beHaviorsLog;
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

